package com.leifu.mvpkotlin.net.rx

import android.content.Context
import com.lfc.myframe.MyApp
import com.lfc.myframe.share.HttpIp
import com.lfc.myframe.share.SP_Params
import com.lfc.myframe.utils.LgU
import com.lfc.myframe.utils.Preference
import com.lfc.myframe.utils.retorfitUtil.GsonConverter.ResponseConverterFactory
import com.mdchina.thelifeorder.api.ApiService
import com.mdchina.thelifeorder.utils.network.NetworkUtil
import com.tamsiree.rxkit.RxTool
import com.tamsiree.rxkit.TLog
import okhttp3.*
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import java.io.File
import java.util.concurrent.TimeUnit


/**
 *创建人:
 *创建时间:2019/6/5 17:24
 *描述:
 */
object RetrofitManager {
    //    val apiService: ApiService by lazy {
//        getRetrofit().create(ApiService::class.java)
//    }
    val apiService: ApiService by lazy {
        getRetrofit(null).create(ApiService::class.java)
    }

    fun getApiS(ctx: Context): ApiService {
        return getRetrofit(ctx).create(ApiService::class.java)
    }

    private var okHttpClient: OkHttpClient? = null

    private fun getRetrofit(ctx: Context?): Retrofit {
        // 获取retrofit的实例
        return Retrofit.Builder()
            .baseUrl(HttpIp.BaseIp)  //自己配置
            .client(getOkHttpClient())
            //使Retrofit支持Rxjava2链式调用
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            //添加转换器  GSON
            .addConverterFactory(ResponseConverterFactory.create())
//            .addConverterFactory(ResponseConverterFactory.create(ctx))
//            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    private fun getOkHttpClient(): OkHttpClient {
//        if (okHttpClient == null) {
        //添加一个log拦截器,打印所有的log
        val httpLoggingInterceptor =
            HttpLoggingInterceptor(HttpLoggingInterceptor.Logger { message: String? ->
                LgU.more("okhttp", message)
            })
        //可以设置请求过滤的水平,body,basic,headers
        httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY

        //设置 请求的缓存的大小跟位置
        val cacheFile = File(MyApp.instance?.baseContext?.cacheDir, "cache")
        val cache = Cache(cacheFile, 1024 * 1024 * 50) //50Mb 缓存的大小

        okHttpClient = OkHttpClient.Builder()
//                .addInterceptor(addQueryParameterInterceptor())  // body
            .addInterceptor(addHeaderInterceptor()) //     head
            .addInterceptor(httpLoggingInterceptor) //日志,所有的请求响应度看到
//            .addNetworkInterceptor(addCacheInterceptor())// 添加缓存
//            .addInterceptor(addCacheInterceptor())// 添加缓存
//            .addInterceptor(NoNetInterceptor())    //将无网络拦截器当做应用拦截器添加
//                .addNetworkInterceptor(NetInterceptor()) //将有网络拦截器当做网络拦截器添加
            .cache(cache)  //添加缓存
            .connectTimeout(60L, TimeUnit.SECONDS).readTimeout(60L, TimeUnit.SECONDS)
            .writeTimeout(60L, TimeUnit.SECONDS).build()
//        }
        return okHttpClient!!
    }

    /**
     * 设置公共参数
     */
    private fun addQueryParameterInterceptor(): Interceptor {
        return Interceptor { chain ->
            val originalRequest = chain.request()
            val request: Request
            val modifiedUrl = originalRequest.url().newBuilder()
                // Provide your custom parameter here
                .addQueryParameter("udid", "d2807c895f0348a180148c9dfa6f2feeac0781b5")
                .addQueryParameter("deviceModel", "").build()

            request = originalRequest.newBuilder().url(modifiedUrl).build()
            chain.proceed(request)
        }
    }

    /**
     * 设置头
     * 1 头和body  key 字典排序（除去空 注意中文）
     * 2 sha1加密
     * 3 md5  32位大写
     */
    private fun addHeaderInterceptor(): Interceptor {
        return Interceptor { chain ->
            val originalRequest = chain.request()
            var requestMethod = originalRequest.method()//请求方式
            var mapRequstData = mutableMapOf<String, String>()

            if (requestMethod == "POST" || requestMethod == "DELETE") {
                if (originalRequest.body() is FormBody) {
//                    val bodyBuilder = FormBody.Builder()
                    val formBody = originalRequest.body() as FormBody
                    for (index in 0 until formBody.size()) {
                        val oldKey = formBody.encodedName(index)
                        val oldValue = formBody.encodedValue(index)
                        if (oldValue.isNotEmpty()) mapRequstData[oldKey] = oldValue
                    }
                }
            } else if (requestMethod == "GET") {
                var queryKeyName = originalRequest.url().queryParameterNames()
                for (s in queryKeyName) {
                    var queryValues = originalRequest.url().queryParameterValues(s)
                    if (queryValues.isNotEmpty()) {
                        var queryValue = queryValues[0]
                        if (queryValue.isNotEmpty()) mapRequstData[s] = queryValue
                    }
                }
            }

            TLog.d(mapRequstData.toString())
            val strSiteKey = HttpIp.BASE_SiteKey
            val strSource = 1.toString() //标识 1=APP 2=PC网页 3=小程序
            val strTicks = (System.currentTimeMillis() / 1000).toString()
            val strAuthToken: String by Preference(SP_Params.Token, "")
//            签名 MD5(sitekey:通信名称;appsecret:密钥;ticksstr:时间戳;authtoken:登录身份（登录时参与加密）)
//            sign
            var strJiaMi =
                "sitekey:" + strSiteKey + ";appsecret:" + HttpIp.BASE_Appsecret + ";ticksstr:" + strTicks + if (strAuthToken.isNullOrBlank()) "" else ";authtoken:$strAuthToken"
//            var strJiaMi = strSiteKey + HttpIp.BASE_Appsecret + strTicks
            TLog.d("md5加密原始:$strJiaMi")
            var strSign = RxTool.Md5(strJiaMi)


//            val strSignature = MD5Utils.md5Password(strSha1).toUpperCase()
            TLog.d("md5加密最终结果:$strSign")
            val requestBuilder = originalRequest.newBuilder()
                // Provide your custom header here
                .header("siteKey", strSiteKey)
                .header("source", strSource)
                .header("ticks", strTicks)
                .header("authToken", strAuthToken)
                .header("sign", strSign)
                .method(originalRequest.method(), originalRequest.body())
            val request = requestBuilder.build()
            chain.proceed(request)
        }
    }

    /**
     * 设置缓存
     */
    private fun addCacheInterceptor(): Interceptor {
        return Interceptor { chain ->
            var request = chain.request()
            if (!NetworkUtil.isConnected()) {
                request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build()
            }
            val response = chain.proceed(request)
            if (NetworkUtil.isConnected()) {
                val maxAge = 0
                // 有网络时 设置缓存超时时间0个小时 ,意思就是不读取缓存数据,只对get有用,post没有缓冲
                response.newBuilder().header("Cache-Control", "public, max-age=" + maxAge)
                    .removeHeader("Retrofit")// 清除头信息，因为服务器如果不支持，会返回一些干扰信息，不清除下面无法生效
                    .build()
            } else {
                // 无网络时，设置超时为4周  只对get有用,post没有缓冲
                val maxStale = 60 * 60 * 24 * 28
                response.newBuilder()
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .removeHeader("nyn").build()
            }
            response
        }
    }
}